www.gusucode.com > VC++ 界面很酷的一款多媒体播放器 > VC++ 界面很酷的一款多媒体播放器/gusucode/xMedia代码注释中/Image.cpp

    //Download by http://www.NewXing.com
/******************************************************************************\
*
*  文件名:    bitmap.cpp
*  作者: 张元一
*
\******************************************************************************/
#include <windows.h>
#include <tchar.h>
#include <math.h>
#include "image.h"

bool	Image::GetPixel(int x,int y,DWORD &pixel)
{
	if(!m_LoadFlag||x<0||x>=m_Width||
		y<0||y>=m_Height)
		return false;
	BYTE temp[4];
	switch(m_BitCount)
	{
	case 1:
		temp[0]=*(m_Data+y*m_LineByte+x/8)>>(7-x%8);
		temp[0]&=0x01;
		pixel=temp[0];
		break;
	case 2:
		temp[0]=*(m_Data+y*m_LineByte+x/4)>>(3-x%4)*2;
		temp[0]&=0x03;
		pixel=temp[0];
		break;
	case 4:
		temp[0]=*(m_Data+y*m_LineByte+x/2)>>(1-x%2)*4;
		temp[0]&=0x0f;
		pixel=temp[0];
		break;
	case 8:
		pixel=*(m_Data+y*m_LineByte+x);
		break;
	case 24:
		temp[0]=*(m_Data+y*m_LineByte+x*3);
		temp[1]=*(m_Data+y*m_LineByte+x*3+1);
		temp[2]=*(m_Data+y*m_LineByte+x*3+2);
		pixel=MAKEDWORD(MAKEWORD(temp[2],0),MAKEWORD(temp[0],temp[1]));
		break;
	case 32:
		temp[0]=*(m_Data+y*m_LineByte+x*4);
		temp[1]=*(m_Data+y*m_LineByte+x*4+1);
		temp[2]=*(m_Data+y*m_LineByte+x*4+2);
		temp[3]=*(m_Data+y*m_LineByte+x*4+3);
		pixel=MAKEDWORD(MAKEWORD(temp[3],temp[2]),MAKEWORD(temp[1],temp[0]));
		break;
	default:
		return false;
	}
	return true;
}
//////////////////////////////////////////
//										//
//函数:Load							//
//目的:读取指定文件					//
//参数:filename	- 要读取的文件名	//
//返回值:成功返回True,否则返回Flase	//
//										//
//////////////////////////////////////////
bool Image::Load(TCHAR* filename)
{
	//如果文件名为空则返回
	if(filename==NULL)
		return false;
	_tcscpy(m_FileName,filename);

	HANDLE fileHandle;		//文件句柄
	BYTE*  fBuffer;			//文件缓冲区
	//打开文件
	fileHandle=CreateFile(filename,GENERIC_READ,
		0, 0, OPEN_EXISTING, 0, 0);
	if(fileHandle==INVALID_HANDLE_VALUE)
		return false;

	DWORD sizeLo,sizeHi;
	DWORD ReadByte;
	//获得文件大小
	sizeLo=GetFileSize(fileHandle,&sizeHi);
	if(sizeLo==0) return false;

	//为文件缓冲区分配内存
	fBuffer=new BYTE[sizeLo];
	if(fBuffer==NULL) return false;
	//将文件读入缓冲区
	ReadFile(fileHandle,fBuffer,sizeLo,&ReadByte,NULL);
	if(ReadByte!=sizeLo) return false;

	//读取文件头
	BITMAPFILEHEADER *bf;
	bf=(BITMAPFILEHEADER*)fBuffer;
	if(bf->bfType!=0x4d42)
	{
		delete fBuffer;
		return false;
	}
	//读取位图信息头
	BITMAPINFOHEADER *bi;
	bi=(BITMAPINFOHEADER*)(fBuffer+sizeof(BITMAPFILEHEADER));
	//如果不是RGB方式则退出
	if(bi->biCompression!=BI_RGB)
	{
		delete fBuffer;
		return false;
	}
	m_Width=bi->biWidth;
	m_Height=bi->biHeight;
	m_BitCount=bi->biBitCount;
	if(m_BitCount!=1&&m_BitCount!=2&&
		m_BitCount!=4&&m_BitCount!=8&&
		m_BitCount!=24&&m_BitCount!=32)
	{
		delete fBuffer;
		return false;
	}

	RGBQUAD *RgbQuad=(RGBQUAD*)(fBuffer+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
	//如果小于8则有调色板
	if(m_BitCount<=8)
	{
		//获取调色板数量
		if(bi->biClrUsed==0)
			m_QuadNum=1<<m_BitCount;
		else
			m_QuadNum=bi->biClrUsed;
		m_RgbQuad=new RGBQUAD[m_QuadNum];
		if(m_RgbQuad==NULL)
		{
			delete fBuffer;
			return false;
		}
		for(int i=0;i<m_QuadNum;i++)
			RgbQuad[i].rgbReserved=i;
		memcpy(m_RgbQuad,(fBuffer+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)),
			sizeof(RGBQUAD)*m_QuadNum);
		RGBQUAD temp;
		for(i=0;i<m_QuadNum;i++)
			for(int j=m_QuadNum-1;j>i;j--)
			{
				/*if(m_RgbQuad[j].rgbBlue<m_RgbQuad[j-1].rgbBlue||
					(m_RgbQuad[j].rgbBlue==m_RgbQuad[j-1].rgbBlue&&
					m_RgbQuad[j].rgbGreen<m_RgbQuad[j-1].rgbGreen)||
					(m_RgbQuad[j].rgbBlue==m_RgbQuad[j-1].rgbBlue&&
					m_RgbQuad[j].rgbGreen==m_RgbQuad[j-1].rgbGreen&&
					m_RgbQuad[j].rgbRed<m_RgbQuad[j-1].rgbRed))*/
				if((m_RgbQuad[j].rgbBlue+m_RgbQuad[j].rgbGreen+m_RgbQuad[j].rgbRed)
					<(m_RgbQuad[j-1].rgbBlue+m_RgbQuad[j-1].rgbGreen+m_RgbQuad[j-1].rgbRed))
				{temp=m_RgbQuad[j];m_RgbQuad[j]=m_RgbQuad[j-1];m_RgbQuad[j-1]=temp;}
			}
		for(i=0;i<m_QuadNum;i++)
			RgbQuad[m_RgbQuad[i].rgbReserved].rgbReserved=i;
	}

	//获取行像素数
	m_LineByte=((m_Width*m_BitCount+31)/32)*4;
	m_Data=new BYTE[m_LineByte*m_Height];
	if(m_Data==NULL)
	{
		delete fBuffer;
		return false;
	}
	memcpy(m_Data,fBuffer+bf->bfOffBits,m_LineByte*m_Height);

	m_LoadFlag=true;
	m_bi=(BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_QuadNum);
	if(m_bi==NULL) return false;
	memcpy(m_bi,fBuffer+sizeof(BITMAPFILEHEADER),
		sizeof(BITMAPINFOHEADER));
	memcpy(m_bi->bmiColors,m_RgbQuad,sizeof(RGBQUAD)*m_QuadNum);
	
	m_ImageType=IMAGE_BMP;
	_tcscpy(m_FileName,filename);
	CloseHandle(fileHandle);
	delete fBuffer;
	return true;
}
//////////////////////////////////////////
//										//
//函数:Display							//
//目的:显示位图到指定区域				//
//参数:hdc			- 设备上下文		//
//		srcrect		- 源矩形			//
//		dstrect		- 目标矩形			//
//		streflag	- 是否拉伸			//
//										//
//返回值:成功返回True,否则返回Flase	//
//										//
//////////////////////////////////////////
bool Image::Display(HDC hdc,RECT srcrect,RECT dstrect,DWORD flag)
{ 
	if(!m_LoadFlag)
		return false;

	m_bi->bmiHeader.biWidth=m_Width;
	m_bi->bmiHeader.biHeight=m_Height;
	if(StretchDIBits(hdc,dstrect.left,dstrect.top,
		dstrect.right-dstrect.left,dstrect.bottom-dstrect.left,
		srcrect.left,srcrect.top,srcrect.right-srcrect.left,
		srcrect.bottom-srcrect.top,m_Data,
		m_bi,
		DIB_RGB_COLORS,flag))
		return true;
	return false;
}